﻿using AutoMapper;
using MediatR;
using Process.Api.Application.Command;
using Process.BLL;
using Process.DAL;
using Process.ErrorCod;
using Process.Infastructure;
using Process.Model;
using System.Threading;

namespace Process.Api.Application.Handler
{
    public class CreateProcessFlowHandler : IRequestHandler<CreateProcessFlowCommand, ApiResult<int>>
    {
        private readonly ProcessDbContext _db;
        private readonly IProcessRepository<ProcessFlow> _flowRepo;
        private readonly IProcessRepository<FlowProcessRelation> _relRepo;
        private readonly ILogger<CreateProcessFlowHandler> logger;

        public CreateProcessFlowHandler(IProcessRepository<ProcessFlow> flowRepo, IProcessRepository<FlowProcessRelation> relRepo, ILogger<CreateProcessFlowHandler> logger, ProcessDbContext db)
        {
            _flowRepo = flowRepo;
            _relRepo = relRepo;
            this.logger = logger;
            _db = db;
        }
        /// <summary>
        /// 添加工艺流程
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult<int>> Handle(CreateProcessFlowCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();

            if (request.ProcessIds == null || request.ProcessIds.Count == 0)
            {
                result.Code = ErrorStatus.Error;
                result.Message = "请至少选择一个工序";
                return result;
            }

            // 流程编号唯一性校验
            if (_flowRepo.GetAllAsync().Any(x => x.FlowCode == request.FlowCode && x.IsDelete == false))
            {
                result.Code = ErrorStatus.Error;
                result.Message = "流程编号已存在";
                return result;
            }

            // 验证所有ProcessIds是否存在
            var existingProcessIds = _db.processinfos
                .Where(x => request.ProcessIds.Contains(x.Id) && x.IsDelete == false)
                .Select(x => x.Id)
                .ToList();

            if (existingProcessIds.Count != request.ProcessIds.Count)
            {
                result.Code = ErrorStatus.Error;
                result.Message = "部分工序不存在或已被删除";
                return result;
            }
            await using var tx = await _db.Database.BeginTransactionAsync(cancellationToken);
            try
            {
                //实例化工艺流程
                var flow = new ProcessFlow
                {
                    FlowCode = request.FlowCode,
                    FlowName = request.FlowName,
                    FlowNumber = request.FlowNumber,
                    Responsible = request.Responsible,
                    Department = request.Department,
                    Status = request.Status,
                    Remark = request.Remark ?? string.Empty,
                    CreateTime = DateTime.Now,
                    Creater = "张三",
                    IsDelete = false

                };
                //添加工艺流程
                var flowId = await _flowRepo.CreateAsync(flow);   

                //批量添加工序工艺关系
                int sort = 1;
                foreach (var pid in existingProcessIds)  // 使用验证过的ProcessIds
                {
                    await _relRepo.CreateAsync(new FlowProcessRelation
                    {
                        ProcessFlowId = flowId,    // 使用数据库中实际的字段名ProcessFlowId
                        ProcessId = pid,
                        Sort = sort++,
                        Remark = request.Remark,
                        CreateTime = DateTime.Now
                    });
                }

                await _db.SaveChangesAsync(cancellationToken);   // 统一一次性保存
                await tx.CommitAsync(cancellationToken);

                result.Code = ErrorStatus.Success;
                result.Data = flowId;
                result.Message = "创建流程成功";
                return result;
            }
            catch (Exception)
            {
                await tx.RollbackAsync(cancellationToken);
                result.Code = ErrorStatus.Error;
                result.Message = "创建流程失败";
                return result;
            }

        }
    }
}
